﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using FieldPDFTools;
using FieldPDFTools.Model;
using Microsoft.Win32;
using System.Windows.Forms;
using Ookii.Dialogs;
using MessageBox = System.Windows.MessageBox;
using System.Text.RegularExpressions;
using System.Text.Json.Serialization;
using System.Text.Json;
using System.IO;
using Microsoft.VisualBasic;
//using iTextSharp.text.pdf;
//using iTextSharp.text;
using System.Windows.Threading;
using static System.Net.Mime.MediaTypeNames;
using System.Drawing;
using PdfSharpCore.Pdf;
using PdfSharpCore;
using PdfSharpCore.Drawing;

namespace FieldPDFTools
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);
            InitializeComponent();
            //获取配置
            var defaultPDFDirectories = new ObservableCollection<PDFDirectory>() {
                    new(){DirName=Environment.GetFolderPath(Environment.SpecialFolder.MyPictures)+"\\"}
            };
            PDFDirectories = JsonSerializer.Deserialize<ObservableCollection<PDFDirectory>>(ConfigHelper.ReadOrSetDefaultSetting(nameof(PDFDirectories), JsonSerializer.Serialize(defaultPDFDirectories)));

            var defaultMatchStr = @".(jpg|png|jpeg)+$";
            MatchStr = ConfigHelper.ReadOrSetDefaultSetting(nameof(MatchStr), defaultMatchStr);

            var defalutOutPath = Environment.CurrentDirectory + @"\OutPut";
            if(!Directory.Exists(defalutOutPath))Directory.CreateDirectory(defalutOutPath);
            //defalutOutPath += @$"\{DateTime.Now:yyyyMMddhhmmss}.pdf";
            OutPath = ConfigHelper.ReadOrSetDefaultSetting(nameof(OutPath), defalutOutPath);

            LoadingVisible = "Collapsed"; 

            var defaultWatermark = "测试水印|3|4|50|45";
            Watermark = ConfigHelper.ReadOrSetDefaultSetting(nameof(Watermark), defaultWatermark);
            this.DataContext = this;
            //this.dataGrid.LoadingRow += new EventHandler<DataGridRowEventArgs>(this.dataGridEquipment_LoadingRow);
            Log = "更新日志：\r\n" +
                "20230213：\r\n" +
                "\t基础构建，实现批量合成图片为pdf；\r\n" +
                "\t输出后，打开输出目录；\r\n" +
                "20231013：\r\n" +
                "\t添加水印功能，使用自定格式字符串字符串，水印字符串用“|”分割，顺序为：字符串|列数|行数|字体大小|旋转角度，可以缺，但顺序不能乱；\r\n" +
                "\t修改部分默认配置；\r\n" +
                "后续计划：" +
                "\t使用独立配置文件\r\n" +
                "20240318：\r\n" +
                "\r配置本地化；" +
                "\t……\r\n" +
                "by Field";
            this.Closed += MainWindow_Closed; ;
        }

        private void MainWindow_Closed(object? sender, EventArgs e)
        {
            ConfigHelper.AddUpdateAppSettings(nameof(PDFDirectories), JsonSerializer.Serialize(PDFDirectories));
            ConfigHelper.AddUpdateAppSettings(nameof(MatchStr), MatchStr);
            ConfigHelper.AddUpdateAppSettings(nameof(OutPath), OutPath);
            ConfigHelper.AddUpdateAppSettings(nameof(Watermark), Watermark);
        }

        public string Log
        {
            get { return (string)GetValue(LogProperty); }
            set { SetValue(LogProperty, value); }
        }

        // Using a DependencyProperty as the backing store for Log.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty LogProperty =
            DependencyProperty.Register("Log", typeof(string), typeof(MainWindow), null);

        //public ObservableCollection<PDFDirectory> PDFDirectorys;

        public ObservableCollection<PDFDirectory> PDFDirectories
        {
            get { return (ObservableCollection<PDFDirectory>)GetValue(PDFDirectoriesProperty); }
            set { SetValue(PDFDirectoriesProperty, value); }
        }

        // Using a DependencyProperty as the backing store for PDFDirectories.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty PDFDirectoriesProperty =
            DependencyProperty.Register("PDFDirectories", typeof(ObservableCollection<PDFDirectory>), typeof(MainWindow), null);

        public string MatchStr
        {
            get { return (string)GetValue(MatchStrProperty); }
            set { SetValue(MatchStrProperty, value);}
        }

        // Using a DependencyProperty as the backing store for matchStr.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty MatchStrProperty =
            DependencyProperty.Register("MatchStr", typeof(string), typeof(MainWindow), null);

        public string OutPath
        {
            get { return (string)GetValue(OutPathProperty); }
            set { SetValue(OutPathProperty, value);}
        }

        // Using a DependencyProperty as the backing store for OutPath.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty OutPathProperty =
            DependencyProperty.Register("OutPath", typeof(string), typeof(MainWindow), null);

        /// <summary>
        /// Visible、Collapsed、Hidden
        /// </summary>
        public string LoadingVisible
        {
            get { return (string)GetValue(LoadingVisibleProperty); }
            set { SetValue(LoadingVisibleProperty, value); }
        }

        // Using a DependencyProperty as the backing store for LoadingVisible.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty LoadingVisibleProperty =
            DependencyProperty.Register("LoadingVisible", typeof(string), typeof(MainWindow), null);

        /// <summary>
        /// 水印
        /// </summary>
        public string Watermark
        {
            get { return (string)GetValue(WatermarkProperty); }
            set { SetValue(WatermarkProperty, value);}
        }

        // Using a DependencyProperty as the backing store for Watermark.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty WatermarkProperty =
            DependencyProperty.Register("Watermark", typeof(string), typeof(MainWindow), null);

        private void Button_Click(object sender, RoutedEventArgs e)
        {
            FolderBrowserDialog folderBrowserDialog = new FolderBrowserDialog();
            var res = folderBrowserDialog.ShowDialog();
            if(res == System.Windows.Forms.DialogResult.Cancel)
            {
                return;
            }
            string path = folderBrowserDialog.SelectedPath;
            PDFDirectories.Add(new() { DirName = path });
        }

        private void Button_Click_1(object sender, RoutedEventArgs e)
        {
            var selectedItems = this.dataGrid.SelectedItems;
            if(selectedItems.Count <= 0)
            {
                MessageBox.Show("未选择条目，无法删除");
                return;
            }
            var ss = selectedItems;
            for(int i=0; i<ss.Count; i++)
            {
                try
                {
                    PDFDirectories.Remove((PDFDirectory)ss[i]);
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.Message);
                }
            }
        }

        private void DataGridEquipment_LoadingRow(object sender, DataGridRowEventArgs e)
        {
            e.Row.Header = e.Row.GetIndex() + 1;
        }

        private List<FileInfo> GetSource()
        {
            var paths = PDFDirectories.ToList();
            var files = new List<FileInfo>();
            paths.ForEach(p => {
                if (p == null || string.IsNullOrEmpty(p.DirName)) return;
                var tempFiles = this.GetFiles(p.DirName);
                if(tempFiles != null && tempFiles.Any()) 
                {
                    files.AddRange(tempFiles);
                }
            });
            var pathsOut = files.FindAll((x) => { 
                Regex regex = new(this.MatchStr);
                if(string.IsNullOrEmpty(x.FullName))return false;
                var re = regex.IsMatch(x.FullName);
                return re;
            });
            return pathsOut;
        }

        public List<FileInfo> GetFiles(string path)
        {
            if (string.IsNullOrEmpty(path) || !Directory.Exists(path)) return new();
            DirectoryInfo directory = new(path);
            var files = directory.GetFiles()?.ToList();
            if(files == null || !files.Any()) return new();
            var dirs = directory.GetDirectories();
            var files2 = new List<FileInfo>();
            if(dirs.Length >= 0)
            {
                foreach (var dir in dirs)
                {
                    files2 = GetFiles(dir.FullName);
                }
            }
            files.AddRange(files2);
            return files;
        }

        private async void Button_Click_2(object sender, RoutedEventArgs e)
        {
            var files = GetSource();
            var paths = files.Select((x)=>x.FullName).ToList();
            LoadingVisible = "Visible";
            await CreateTextPDFX(paths);
            //var ms = JsonSerializer.Serialize(paths);
            //MessageBox.Show("第一个路径："+paths[0]);
            //string newStr = Regex.Unescape(ms);
            //MessageBox.Show(newStr);
        }

        public async Task CreateTextPDFX(List<string> paths)
        {
            string outPath = OutPath;
            string watermark = Watermark;
            await Task.Run(() =>
            {
                //1. 定义文档对象
                using PdfDocument document = new PdfDocument();
                document.Info.Author = "作者";
                try
                {
                    for (int i = 0; i < paths.Count; i++)
                    {
                        var path = paths[i];
                        //2. 新增一页
                        PdfPage page = document.AddPage();
                        using XGraphics xGraphics = XGraphics.FromPdfPage(page);
                        using XImage image = XImage.FromFile(path);
                        // 设置纸张大小
                        page.Width = image.PointWidth;
                        page.Height = image.PointHeight;
                        xGraphics.DrawImage(image, 0, 0);

                        //XFont font = new XFont("SimHei", 50);
                        //XBrush brush = new XSolidBrush(XColor.FromArgb(255, 255, 0, 50));
                        //XStringFormat stringFormat = new XStringFormat();
                        //stringFormat.Alignment = XStringAlignment.Center;
                        //stringFormat.LineAlignment = XLineAlignment.Center;
                        //xGraphics.DrawString(
                        //       $"xxx公司版权所有",
                        //       font,
                        //       brush,
                        //       new XPoint(500, 500),
                        //        stringFormat);
                        if (!string.IsNullOrEmpty(watermark))
                        {
                            var ws = watermark.Split('|');
                            string str = ws[0];
                            int fs = 50;
                            int xn = 3, yn = 4;
                            int ang = 90;
                            
                            if(ws.Length > 2)
                            {
                                if (!int.TryParse(ws[1], out xn))xn = 3;
                                if (!int.TryParse(ws[2], out yn))yn = 3;
                                if (ws.Length > 3)
                                {
                                    if (!int.TryParse(ws[3], out fs))fs = 50;
                                    if (ws.Length > 4)
                                    {
                                        if (!int.TryParse(ws[4], out ang)) ang = 90;
                                    }
                                };
                            }
                            
                            //水印开始
                            XFont font = new XFont("SimHei", fs, XFontStyle.BoldItalic);
                            // 计算长度
                            //var size = xGraphics.MeasureString(str, font);

                            // 定义旋转中心
                            xGraphics.TranslateTransform(page.Width / 2, page.Height / 2);
                            xGraphics.RotateTransform(ang);
                            //xGraphics.RotateTransform(-Math.Atan(page.Height / page.Width) * 180 / Math.PI);
                            xGraphics.TranslateTransform(-page.Width / 2, -page.Height / 2);

                            // 字符样式
                            var format = new XStringFormat();
                            format.Alignment = XStringAlignment.Near;
                            format.LineAlignment = XLineAlignment.Near;

                            //画刷
                            XBrush brush = new XSolidBrush(XColor.FromArgb(255, 255, 42, 25));
                            for (int j = 0; j < xn; j++)
                            {
                                for (int k = 0; k < yn; k++)
                                {
                                    xGraphics.DrawString(str, font, brush,
                                        new XPoint(page.Width / xn * (j + 0.5), page.Height / yn * (k + 0.5)),
                                        format);
                                }
                            }
                            //for (int j = 0; j < 3; j++)
                            //{
                            //    xGraphics.DrawString(watermark, font, brush,
                            //    new XPoint((page.Width - size.Width) / (1.5 + j * 0.5), (page.Height - size.Height) / (1.5 + j * 0.5)),
                            //    format);
                            //}
                        }

                        image.Dispose();
                        xGraphics.Dispose();
                    }
                    outPath += @$"\{DateTime.Now:yyyyMMddhhmmss}.pdf";
                    document.Save(outPath);
                    MessageBox.Show("生成成功");
                    OpenFilePath(outPath);
                }
                catch (Exception ex)
                {
                    MessageBox.Show("生成失败:" + ex.Message);
                }
                finally
                {
                    document.Dispose();
                    Dispatcher.BeginInvoke(() =>
                    {
                        LoadingVisible = "Collapsed";
                    });
                }
            });
            
        }

        /// <summary>
        /// 打开文件路径并选中文件
        /// </summary>
        /// <param name="fullNamePath">文件的完整路径</param>
        public void OpenFilePath(string fullNamePath)
        {
            System.Diagnostics.Process.Start("Explorer", "/select," + fullNamePath);
        }
    }

    public class PDFParam
    {
        public string OutPath { get; set; }
        public string WaterMarkText { get; set; }
        public string WaterMarkImgUrl { get; set; }
        public string TextColor { get; set; }
        public double FontSize { get; set; }
        public string FontFamily { get; set; }
    }
}
